package com.controller.pay;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.config.alipay.AlipayConfig;
import com.entity.TbOrder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import com.service.OrderService;
import com.util.StatusCode;
import com.vo.ResultVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.sql.Time;
import java.util.*;

@Controller
@Api(tags = "支付模块")
public class PayController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private AlipayConfig alipayConfig;

    //必须加ResponseBody注解，否则spring会寻找thymeleaf页面
    //传入两个参数，订单金额以及订单id;
    @ResponseBody
    @GetMapping("/pay/alipay")
    @ApiOperation(value = "支付操作，生成支付页面", notes = "订单支付")
    public String alipay(HttpSession session, HttpServletRequest request, @RequestParam("order_id") String order_id) throws AlipayApiException {
        TbOrder tbOrder = orderService.queryOrderById(order_id);
        //调用封装好的方法（给支付宝接口发送请求）
        return sendRequestToAlipay(order_id, tbOrder.getPayMoney().floatValue(), tbOrder.getUsername());
    }



    /**
     * //支付宝官方提供的接口
     * @param outTradeNo  订单号
     * @param totalAmount 订单金额
     * @param subject     订单名称
     * @return
     * @throws AlipayApiException
     */
    private String sendRequestToAlipay(String outTradeNo, Float totalAmount, String subject) throws AlipayApiException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGATEWAY_URL(), alipayConfig.getAPP_ID(), alipayConfig.getAPP_PRIVATE_KEY(), alipayConfig.getFORMAT(),
                alipayConfig.getCHARSET(), alipayConfig.getALIPAY_PUBLIC_KEY(), alipayConfig.getSIGN_TYPE());

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(alipayConfig.getRETURN_URL());
        alipayRequest.setNotifyUrl(alipayConfig.getNOTIFY_URL());

        //商品描述（可空）
        String body = "";
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\","
                + "\"total_amount\":\"" + totalAmount + "\","
                + "\"subject\":\"" + subject + "等商品" + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        return result;
    }

    /**
     * 同步回调
     * @param request
     * @param session
     * @param model
     * @return
     * @throws AlipayApiException
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/returnurl")
    public String returnUrlMethod(HttpServletRequest request, HttpSession session, Model model) throws AlipayApiException, UnsupportedEncodingException {
        System.out.println("=================================同步回调=====================================");

        // 获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        System.out.println(params);//查看参数都有哪些
        //验证签名（支付宝公钥）
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getALIPAY_PUBLIC_KEY(), alipayConfig.getCHARSET(), alipayConfig.getSIGN_TYPE()); // 调用SDK验证签名
        //验证签名通过
        if (signVerified) {
            // 商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            // 支付宝交易流水号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

            // 付款金额
            float money = Float.parseFloat(new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8"));

            System.out.println("商户订单号=" + out_trade_no);
            System.out.println("支付宝交易号=" + trade_no);
            System.out.println("付款金额=" + money);
            //修改订单状态
            TbOrder tbOrder = new TbOrder();
            tbOrder.setId(out_trade_no);
            tbOrder.setPayStatus("1");
            tbOrder.setOrderStatus("1");
            tbOrder.setTransactionId(trade_no);
            tbOrder.setPayTime(new Date());
            orderService.updateOrderStatus(tbOrder);
			/*
			################################
			*/
            //跳转到提示页面（成功或者失败的提示页面）
            model.addAttribute("order_id", out_trade_no);
            model.addAttribute("msg", "支付成功");
            return "common/paysuccess";
        } else {
            //跳转到提示页面（成功或者失败的提示页面）
            model.addAttribute("flag", 0);
            model.addAttribute("msg", "支持");
            return "common/paysuccess";
        }
    }

    /**
     * 提供支付状态查询接口
     *
     */

    @ResponseBody
    @PostMapping("/getpaystatus")
    @ApiOperation(value = "根据订单号查询支付状态", notes = "支付状态")
    public ResultVo getPayStatus(String order_id){
        TbOrder tbOrder = orderService.queryOrderById(order_id);
        if(Objects.isNull(tbOrder)) return new ResultVo(false,StatusCode.SERVERERROR,"订单不存在");
        int i = orderService.queryPayStatus(order_id);
        if(i == 1){
            return new ResultVo(true,StatusCode.OK,"已支付",tbOrder);
        }else if (i == 0){
            return new ResultVo(true,StatusCode.OK,"未支付",tbOrder);
        }
        return new ResultVo(true, StatusCode.OK,"支付失败",tbOrder);
    }

}
